package com.zelma.house.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.zelma.common.utils.R;
import com.zelma.house.dao.AreaDao;
import lombok.SneakyThrows;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zelma.common.utils.PageUtils;
import com.zelma.common.utils.Query;

import com.zelma.house.dao.ResourceDao;
import com.zelma.house.entity.ResourceEntity;
import com.zelma.house.service.ResourceService;


@Service("resourceService")
@SuppressWarnings("all")
public class ResourceServiceImpl extends ServiceImpl<ResourceDao, ResourceEntity> implements ResourceService {

    @Autowired
    private AreaDao areaDao;

    @Autowired
    private RestHighLevelClient client;

    @Override
    public PageUtils queryPage(Map<String, Object> params) throws IOException {
        QueryWrapper<ResourceEntity> w = new QueryWrapper<>();
        IPage<ResourceEntity> page = this.page(
                new Query<ResourceEntity>().getPage(params),
                w
        );
//        es添加
        List<ResourceEntity> list = baseMapper.selectList(w);
        for (ResourceEntity resourceEntity : list) {
            IndexRequest request = new IndexRequest("house");
            request.id(resourceEntity.getResourceId()+"");
            String jsonString = JSON.toJSONString(resourceEntity);
            request.source(jsonString, XContentType.JSON);
            IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
        }
        return new PageUtils(page);
    }

//    查询传过来的楼盘id所拥有的新房及二手房
    @Override
    public List<ResourceEntity> saleDetails(Integer saleId) {
        QueryWrapper<ResourceEntity> w = new QueryWrapper<>();

//        判断是否是本楼盘信息
        w.eq("sale_id",saleId);

//        获取新房及二手房
        w.ne("resource_status",2);

        List<ResourceEntity> resourceEntities = baseMapper.selectList(w);

        return resourceEntities;
    }

//    查询传过来的楼盘id所拥有的出租房
    @Override
    public List<ResourceEntity> saleRentDetails(Integer saleId) {
        QueryWrapper<ResourceEntity> w = new QueryWrapper<>();

//        判断是否是本楼盘信息
        w.eq("sale_id",saleId);

//        获取出租房
        w.eq("resource_status",2);

        List<ResourceEntity> resourceEntities = baseMapper.selectList(w);

        return resourceEntities;
    }

    @Override
    public R combatGains(Integer resourceStatus, Integer agentId) {
//        在前台获取经济人id,得到本经纪人所售卖/出租的房屋
//        先判断经纪人
        QueryWrapper<ResourceEntity> w = new QueryWrapper<>();
        w.eq("agent_id",agentId);
        List<ResourceEntity> a = baseMapper.selectList(w);
        if(a==null){
//            如果经纪人无销售房屋
            return R.error().put("msg","该经纪人目前销售房屋为0");
        }
//        判断售出状态    除去未销售为租赁状态
        w.eq("resource_sold_status",1);
//        判断是出租屋/新房,二手房
        if(resourceStatus==2){
            w.eq("resource_status",2);
            w.orderByDesc("resource_update_date");
            List<ResourceEntity> resourceEntities = baseMapper.selectList(w);
            return R.ok().put("msg","已租赁房屋展示成功").put("resourceEntities",resourceEntities);
        }
        w.ne("resource_status",2);
        w.orderByDesc("resource_update_date");
        List<ResourceEntity> resourceEntities = baseMapper.selectList(w);
        return R.ok().put("msg","已售出房屋展示成功").put("resourceEntities",resourceEntities);
    }

    @Override
    public R egisa(Integer resourceId) throws IOException {
        ResourceEntity resourceEntity = baseMapper.selectById(resourceId);
//        判断审核通过1
        resourceEntity.setResourceAuditStatus(1);
        baseMapper.updateById(resourceEntity);
//        es修改审核状态为通过
        UpdateRequest updateRequest = new UpdateRequest("house",resourceId+"");
//        设置一个过期时间
        updateRequest.timeout("1s");
        updateRequest.doc(JSON.toJSONString(updateRequest),XContentType.JSON);
        client.update(updateRequest,RequestOptions.DEFAULT);

        return R.ok().put("msg","es修改成功");
//        es的底层原理
//                倒排索引为啥这么快

    }

    @SneakyThrows
    @Override
    public PageUtils homeFunEslist(Map<String, Object> params)  {
        SearchRequest searchRequest = new SearchRequest("resource");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        String sname = (String) params.get("sname");
        if (sname!=null && sname!="") {
            boolQueryBuilder.must(QueryBuilders.matchQuery("resource_name",sname));
        }
        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);

        int page=Integer.valueOf((String)params.get("page"));
        int size=Integer.valueOf((String)params.get("size"));
        searchSourceBuilder.from((page-1)*size);
        searchSourceBuilder.size(size);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        TotalHits totalHits = hits.getTotalHits();
// the total number of hits, must be interpreted in the context of totalHits.relation
        long numHits = totalHits.value;
// whether the number of hits is accurate (EQUAL_TO) or a lower bound of the total (GREATER_THAN_OR_EQUAL_TO)
        TotalHits.Relation relation = totalHits.relation;
        float maxScore = hits.getMaxScore();
        SearchHit[] searchHits = hits.getHits();
        ArrayList<ResourceEntity> list = new ArrayList<>();
        for (SearchHit hit : searchHits) {
            // do something with the SearchHit
            String index = hit.getIndex();
            String id = hit.getId();
            float score = hit.getScore();
            String sourceAsString = hit.getSourceAsString();
            ResourceEntity typeEntity = JSON.parseObject(sourceAsString, new TypeReference<ResourceEntity>() {
            });
            list.add(typeEntity);
        }
        return new PageUtils(list, (int) numHits,size,page);
    }

    //原生定时任务(单机部署，不支持集群）
    //@Scheduled(cron = "/5 * * * * * ?") //触发器
    public void ScheduledUpResource(){
        System.out.println("5秒查询一次数据库，将房源信息上传es");//任务
    }



}